package com.yzc35326.sigleton;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author 35326
 * 2021/3/27 10:42
 *
 * 单例模式的八种实现方法
 */
public class SingletonTest {
	public static void main(String[] args) {

	}

	@Test
	/**
	 * 测试单例模式的第一种实现方法：静态常量
	 * 优点：
	 * 在类装载的时候，就进行了初始化。避免了线程同步的问题。
	 *
	 * 缺点：
	 * 不能达到懒加载的效果。
	 *
	 * 结论：这种单例模式可用，但是会造成内存浪费
	 */
	public void test1(){
	     Singleton1 singleton1 = Singleton1.getInstance();
		System.out.println(singleton1);
		Class<Singleton1> singleton1Class = Singleton1.class;
		try {
			//这种方法会抛出访问修饰符异常
//			Singleton1 singleton11 = singleton1Class.newInstance();
			try {
				Constructor<Singleton1> constructor = singleton1Class.getDeclaredConstructor();
				constructor.setAccessible(true);
				Singleton1 singleton11 = constructor.newInstance();
				System.out.println(singleton11);
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} finally {

			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 测试静态代码块的代码
	 */
	@Test
	public void test2(){
		System.out.println(Singleton2.getInstance()==Singleton2.getInstance());
	}

	public void test3(){

	}
}

/**
 * 静态常量
 */
class Singleton1{
	private static final Singleton1 instance = new Singleton1();

	private Singleton1(){

	}

	public static Singleton1 getInstance(){
		return instance;
	}
}

/**
 * 单例模式的第二种写法：静态代码块
 * 优缺点和第一种方法一样
 */
class Singleton2{
	static {
		instance=new Singleton2();

	}

	private final static Singleton2 instance ;
	private static int i;
	private Singleton2(){

	}

	public static Singleton2 getInstance() {
		return instance;
	}
}

class Singleton3{
		private static Singleton3 instance;
		private Singleton3(){

		}

	public static Singleton3 getInstance() {
		if(instance==null){
			instance=new Singleton3();
		}

		return instance;
	}
}

class Singleton4{
	private static Singleton4 instance;

	private Singleton4(){

	}

	public static Singleton4 getInstance() {
		if(instance==null){
			synchronized(Singleton4.class) {
				if(instance==null){
					instance=new Singleton4();
				}
			}

		}

		return instance;
	}
}

/**
 * 静态内部类实现单例模式
 */
class Singleton5{

	private static class SingletonInstance{
		private static final Singleton5 instance = new Singleton5();
	}
	public Singleton5 getInstance(){
		return SingletonInstance.instance;
	}

	private Singleton5(){

	}

}